/* 
 * File:   fe_ode.h
 * Author: boyan
 *
 * Created on September 17, 2008, 12:50 PM
 */

#ifndef _FE_ODENS_H
#define	_FE_ODENS_H

/****************************************************************************/
/* this is a time-integrator for the following equation  */
/*       c0 u_t + c1 (a.grad)u - c2 (u.grad)b - c3 mu laplace(u) + c4 grad(p) = f  */
/*       div(u) = 0   */
/* from t0 to t1 with step dt */
/*   c0-c4 -- coefficients, by default set to 1 */
/*   a     -- convection coefficient */
/*   b     -- reaction  coefficient  */
/*   mu    -- viscosity = 1/Re */
/*   f     -- body force */
/****************************************************************************/
/* IMPORTANT REMARKS: */
/*    - if t1 < t0 then dt must be negative to avoid endles loop */
/*    - to solve standard Navier-Stokes set 
            -- mu=1/re
            -- a = u    ??
            -- b = 0  and/or c2 = 0
      - to solve Navier-Stokes adjoint set
            -- mu=1/re
            -- a = b = state velocity
            -- c0 = c1 = c2 = -1
            -- give t1 < t0 and negative dt
 */

#include "vecs.h"
#include "grid3d.h"
#include "fe_matr.h"

typedef struct fe_odens_s
{
    const char *nsode_name;
    /* problem parameters */
    double t0, t1, dt;      /* start time, stop time and time step */
    int  n, N;          /* current step and total steps */
    double mu;
    double *coefs;
    vector *a;
    vector *b;
    vector *f;
    /* grid and finite elements to be used */
    grid3d_t *grid;
    unsigned elemU;
    unsigned elemP;
    int reassemble;
    int symmetric;    
    /* solution and auxillary vectors */
    vector *u0, *u, *r, *t;
    scalar *p0, *p;
    scalar *phi0, *phi;
    /* system matrix */
    fe_matr_t *mat;
    void *poisson_solver;
    
    /* user input through call-back routines */
    
    /* the following must set the boundary and initial conditions appropriately */
    void (*set_IC)(vector *u, struct fe_odens_s *nsti);
    void (*set_BC)(vector *u, struct fe_odens_s *nsti);
    /* the following must store the soltion and may set the parameter fields a 
                        and b appropriately */
    void (*before_time_step)(struct fe_odens_s *nsti);
    void (*after_time_step)(struct fe_odens_s *nsti);
    
    void *user_data;
    
} fe_odens_t;

#ifdef	__cplusplus
extern "C" {
#endif

void init_ns_time_integrator(struct fe_odens_s *nsti);

void  run_ns_time_integrator(struct fe_odens_s *nsti);

void done_ns_time_integrator(struct fe_odens_s *nsti);




#ifdef	__cplusplus
}
#endif

#endif	/* _FE_ODENS_H */

